package com._54programer.ws;

import com._54programer.ws.handler.HeartBeatHandler;
import com._54programer.ws.handler.WsServerHandler;

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.IdleStateHandler;

/**
 * @author SN
 * @date Created by on 2019/11/29
 * @description
 */
public class WsServerInitializer extends ChannelInitializer<SocketChannel> {

    @Override
    protected void initChannel(SocketChannel ch) throws Exception {

        ChannelPipeline pipeline = ch.pipeline();

        /**
         * 用于支持http协议
         * HttpServerCodec: websocket基于http协议, 所以需要http编解码器
         * ChunkedWriteHandler: 对写大数据流的支持
         * HttpObjectAggregator：对httpMessage进行聚合，聚合成FullHttpRequest或FullHttpResponse，几乎在netty中的编程，都会使用到此hanler
         */
        pipeline.addLast(new HttpServerCodec());
        pipeline.addLast(new ChunkedWriteHandler());
        pipeline.addLast(new HttpObjectAggregator(10240));

        /**
         * 心跳检测
         * IdleStateHandler: 空闲检测
         * 参数: 读空闲、写空闲、读写空闲
         * 针对客户端，如果在1分钟时没有向服务端发送读写心跳(ALL)，则主动断开
         * 如果是读空闲或者写空闲，不处理
         */
        pipeline.addLast(new IdleStateHandler(20, 30, 120));
        //自定义的空闲状态检测
        pipeline.addLast(new HeartBeatHandler());
        

        

        /**
         	* 自定义handler
         */
        pipeline.addLast(new WsServerHandler());
        /**
         	* 用于支持websocket协议
         * WebSocketServerProtocolHandler
         * /ws：服务器处理的协议，指定给客户端连接访问的路由
         	* 该handler会帮你处理握手动作
         * websocket是以frames进行数据传输, 不同的数据类型对应不同的frames
         */
        pipeline.addLast(new WebSocketServerProtocolHandler("/ws"));

        // 需要在握手时获得url后面的参数 则需要按以下顺序 pipeline.addLast
        //TODO....順序必须控制 自定义handler 在 用于支持websocket协议 前面
    }

}